import React, { useEffect, useState } from 'react';
import {
  Space,
  Card,
  Form,
  Checkbox,
  Input,
  Cascader,
  Select,
  Upload,
  Button,
  Table,
  Modal,
  Spin,
  message
} from 'antd';
import type { UploadFile } from 'antd/es/upload/interface';
import {
  ExclamationCircleFilled,
  InfoCircleOutlined,
  UploadOutlined
} from '@ant-design/icons';
import Cookies from 'js-cookie';
import columns from '../../components/columns/companyColumns';
import hasAuthority from '../../components/hasAuthority';
import { useStore, observer } from '../../store/company/storeHook';
import * as patterns from '../../data/patterns';
import { booleanOptions } from '../../data/statusData';
import { trimObject } from '../../utils/dataUtils';

const { TextArea } = Input;

const CompanyList: React.FC = () => {
  const [searchForm] = Form.useForm();
  const [editForm] = Form.useForm();
  const [messageApi, contextHolder] = message.useMessage();
  const [modal, modalContextHolder] = Modal.useModal();

  const [isModalOpen, setIsModalOpen] = useState<boolean>(false);

  const store: any = useStore();

  const [isOwner, setIsOwner] = useState<boolean>(false);
  const [logo, setLogo] = useState<string | null>(null);
  const [logoId, setLogoId] = useState<string | null>(null);
  const [fileList, setFileList] = useState<UploadFile[]>([]);

  const xsrfToken: string = Cookies.get('XSRF-TOKEN') || 'XSRF-TOKEN';

  const rowSelection = {
    onChange: (selectedRowKeys: React.Key[], selectedRows: any[]) => {
      store.company.selectRecord(selectedRows[0]);
    },
    getCheckboxProps: (record: any) => ({
      name: record.id
    })
  };

  const pagination = {
    showSizeChanger: true,
    showQuickJumper: true,
    pageSizeOptions: [10, 20, 30, 40, 50, 100],
    current: store.company.current + 1,
    pageSize: store.company.pageSize,
    total: store.company.total,
    onChange: (page: number, pageSize: number) => {
      store.company.setPageSize(pageSize);
      search(page - 1);
    },
    onShowSizeChange: (current: number, size: number) => {
      store.company.setPageSize(size);
      search(current - 1);
    }
  };

  const search = (pageNumber: number) => {
    const values = getSearchValues();
    store.company.fetchData(values.keyword, values.city, values.active, values.owner, pageNumber);
  };

  const getSearchValues = () => {
    const values: any = searchForm.getFieldsValue(true);
    values.keyword = (values.keyword as string || '').trim();
    return values;
  };

  const editRecord = (record?: any) => {
    store.company.selectRecord(record);
    const data: any = store.company.getEditRecord();
    setIsOwner(!data.id || data.createdBy === store.currentUser.userData.username);
    if (data.logo) {
      const logo: string = data.logo.startsWith('/') ? data.logo : ('/' + data.logo);
      const list: UploadFile[] = [{
        uid: new Date().getTime() + '',
        name: 'logo',
        status: 'done',
        url: logo
      }];
      if (!(fileList.length === list.length && list.length === 1 && fileList[0].url === list[0].url)) {
        setFileList(list);
      }
    } else {
      if (!(fileList.length === 0)) {
        setFileList([]);
      }
    }
    setLogo(data.logo);
    setLogoId(null);
    setIsModalOpen(true);
    editForm.resetFields();
    editForm.setFieldsValue(data);
  };

  const deleteRecord = () => {
    if (!store.company.record) {
      messageApi.info('请选择要删除的记录');
      return;
    }
    modal.confirm({
      title: '确定删除当前选中的记录吗？',
      icon: <ExclamationCircleFilled />,
      onOk() {
        store.company.deleteData().then((res: any) => {
          if (res.success) {
            messageApi.info('删除成功');
            search(store.company.current);
          } else {
            messageApi.error(res.message);
          }
        });
      },
      onCancel() {}
    });
  };

  const saveRecord = (values: any) => {
    if (store.company.saving) {
      return;
    }
    values.cityId = values.city && values.city[1] ? values.city[1] : '';
    values.logo = logo;
    values.logoId = logoId;
    editForm.setFieldsValue(trimObject(values));
    store.company.saveData(values).then((res: any) => {
      store.company.setSaving(false);
      if (res.success) {
        setIsModalOpen(false);
        messageApi.info('保存成功');
        search(store.company.current);
      } else {
        messageApi.error(res.message);
      }
    });
  };

  useEffect(() => {
    const values = store.company.conditions;
    store.company.fetchData(values.keyword, values.city, values.active, values.owner, values.pageNumber);
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  const forbiddenComponent: React.ReactNode = hasAuthority(store, 'authorized');
  if (forbiddenComponent) {
    return forbiddenComponent;
  }

  return (
    <>
      {contextHolder}
      {modalContextHolder}
      <Space
        direction="vertical"
        size={[0, 16]}
        style={{ width: '100%', padding: 16 }}
      >
        <Card
          size="small"
          title={
            <Space style={{ paddingTop: 8, paddingBottom: 16 }}>
              <Space.Compact block>
                <Button
                  disabled={store.company.loading}
                  type="primary"
                  htmlType="button"
                  onClick={() => search(0)}
                >
                  查询
                </Button>
                <Button
                  disabled={store.company.loading}
                  htmlType="button"
                  onClick={() => store.company.resetConditions(searchForm)}
                >
                  重置
                </Button>
              </Space.Compact>
              <Space.Compact block>
                <Button
                  disabled={store.company.loading}
                  type="primary"
                  htmlType="button"
                  onClick={() => editRecord(null)}
                >
                  新增
                </Button>
                <Button
                  disabled={store.company.loading}
                  type="primary"
                  htmlType="button"
                  danger
                  onClick={deleteRecord}
                >
                  删除
                </Button>
              </Space.Compact>
            </Space>
          }
          style={{ paddingTop: 12 }}
        >
          <Form
            form={searchForm}
            name="searchForm"
            autoComplete="off"
            colon={false}
            layout="inline"
            disabled={store.company.loading}
            initialValues={store.company.conditions}
            className="search-form"
          >
            <Form.Item
              name="keyword"
              label="关键词"
            >
              <Input
                autoFocus
                maxLength={32}
                placeholder="名称"
                style={{ width: 160 }}
              />
            </Form.Item>
            <Form.Item
              name="city"
              label="城市"
            >
              <Cascader
                options={store.company.cityOptions}
                showSearch
                style={{ width: 160 }}
              />
            </Form.Item>
            <Form.Item
              name="active"
              label="可用"
            >
              <Select
                options={booleanOptions}
                style={{ width: 80 }}
              />
            </Form.Item>
            <Form.Item
              name="owner"
              label="由当前用户创建"
            >
              <Select
                options={booleanOptions}
                style={{ width: 80 }}
              />
            </Form.Item>
          </Form>
        </Card>
        <Table
          columns={columns(booleanOptions, editRecord)}
          dataSource={store.company.data}
          rowKey="id"
          loading={store.company.loading}
          bordered
          scroll={{ x: 'max-content' }}
          rowSelection={{
            type: 'radio',
            selectedRowKeys: store.company.record ? [store.company.record.id] : [],
            ...rowSelection
          }}
          pagination={pagination}
        />

        <Modal
          title="公司"
          open={isModalOpen}
          maskClosable={false}
          destroyOnHidden
          forceRender
          closable={!store.company.saving}
          confirmLoading={store.company.saving}
          style={{ minWidth: 320 }}
          onOk={() => editForm.submit()}
          onCancel={() => {
            if (!store.company.saving) setIsModalOpen(false)
          }}
          footer={(_, { OkBtn, CancelBtn }) => (
            isOwner ? <><OkBtn /><CancelBtn /></> : null
          )}
        >
          <Spin spinning={store.company.saving}>
            <Form
              form={editForm}
              name="editForm"
              autoComplete="off"
              labelCol={{ span: 6 }}
              wrapperCol={{ span: 16 }}
              preserve={false}
              onFinish={saveRecord}
              onFinishFailed={() => messageApi.warning('数据校验错误')}
            >
              <Form.Item
                name="name"
                label="名称"
                rules={[{ required: true, message: '名称不能为空' }]}
              >
                <Input maxLength={32} />
              </Form.Item>
              <Form.Item
                name="city"
                label="城市"
                rules={[{ required: true, message: '城市不能为空' }]}
              >
                <Cascader
                  options={store.company.cityOptions}
                  showSearch
                />
              </Form.Item>
              <Form.Item
                name="active"
                valuePropName="checked"
                wrapperCol={{ sm: { offset: 6, span: 16 }, xs: { span: 24 } }}
              >
                <Checkbox>可用</Checkbox>
              </Form.Item>
              <Form.Item
                name="address"
                label="地址"
              >
                <Input maxLength={128} />
              </Form.Item>
              <Form.Item
                name="website"
                label="官网"
                rules={[
                  { pattern: patterns.websitePattern, message: '官网格式不正确' }
                ]}
              >
                <Input maxLength={64} />
              </Form.Item>
              <Form.Item
                name="email"
                label="Email"
                rules={[
                  { pattern: patterns.emailPattern, message: 'Email格式不正确' }
                ]}
              >
                <Input maxLength={64} />
              </Form.Item>
              <Form.Item
                name="telephone"
                label="电话"
                rules={[
                  { pattern: patterns.phonePattern, message: '电话格式不正确' }
                ]}
                tooltip={{ title: '格式：(2-3位区号)-(7-8位电话号码)-(1-4位分机号，可无分机号)', icon: <InfoCircleOutlined /> }}
              >
                <Input maxLength={32} />
              </Form.Item>
              <Form.Item
                name="remark"
                label="备注"
              >
                <TextArea
                  maxLength={256}
                  rows={3}
                />
              </Form.Item>
              <Form.Item
                name="_logo"
                label="LOGO"
              >
                { isOwner ?
                  <Upload
                    accept=".jpg,.jpeg,.png"
                    action="/api/upload"
                    maxCount={1}
                    name="file"
                    headers={{'X-XSRF-TOKEN': xsrfToken}}
                    fileList={fileList}
                    onChange={({ file, fileList }) => {
                      setFileList(fileList);
                      if (fileList.length === 0) {
                        setLogo(null);
                        setLogoId(null);
                      } else if (fileList[0].status === 'done') {
                        const data = fileList[0].response.data;
                        fileList[0].uid = data.id;
                        fileList[0].name = data.filename;
                        fileList[0].status = 'done';
                        fileList[0].url = '/api/download/' + data.id;
                        setLogo(null);
                        setLogoId(data.id);
                        setFileList(fileList);
                      }
                    }}
                  >
                    <Button icon={<UploadOutlined />}>
                      上传
                    </Button>
                  </Upload> :
                  <Upload
                    accept=".jpg,.jpeg,.png"
                    action="/api/upload"
                    maxCount={1}
                    name="file"
                    headers={{'X-XSRF-TOKEN': xsrfToken}}
                    fileList={fileList}
                    listType="picture-card"
                    className="placeholder-upload"
                  >
                    <Button />
                  </Upload>
                }
              </Form.Item>
            </Form>
          </Spin>
        </Modal>
      </Space>
    </>
  );
};

export default observer(CompanyList);
